package org.halk.nio;

import org.junit.Test;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.StandardCharsets;

/**
 * @author halk
 * @date 2023/4/11
 */
public class NIOFileChannelDemo {

    /**
     * 将文字写入到指定文件中
     * “str” --》 buffer缓冲区 --》 fileChannel ---》 指定的文件
     *
     * @throws IOException
     */
    @Test
    public void localFileWrite() throws IOException {
        String str = "nihao";
        //创建一个文件输出连用来获取channel
        FileOutputStream fileOutputStream = new FileOutputStream("D://tmp.txt");
        FileChannel fileChannel = fileOutputStream.getChannel();

        //创建一个缓冲区
        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);

        //将str放入到缓冲区
        byteBuffer.put(str.getBytes(StandardCharsets.UTF_8));

        //翻转缓冲区
        byteBuffer.flip();

        //将缓冲区的内容写入到channel中
        fileChannel.write(byteBuffer);

        fileOutputStream.close();
    }

    @Test
    public void localFileRead() throws IOException {
        //通过FileInputStream获取channel
        File file = new File("D://tmp.txt");
        FileInputStream fileInputStream = new FileInputStream(file);
        FileChannel channel = fileInputStream.getChannel();

        //读取到缓冲区
        ByteBuffer byteBuffer = ByteBuffer.allocate((int) file.length());
        channel.read(byteBuffer);

        //将缓冲区的内容打印
        System.out.println(new String(byteBuffer.array()));
    }

    /**
     * 使用同一个buffer完成对文件的读取与写入
     *
     * @throws IOException
     */
    @Test
    public void localFileReadWrite() throws IOException {
        FileInputStream fileInputStream = new FileInputStream("1.txt");
        FileChannel channel01 = fileInputStream.getChannel();
        FileOutputStream fileOutputStream = new FileOutputStream("2.txt");
        FileChannel channel02 = fileOutputStream.getChannel();

        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);

        while (true) {
            byteBuffer.clear();
            int read = channel01.read(byteBuffer);
            System.out.println("read: " + read);
            if (read == -1) {
                break;
            }
            byteBuffer.flip();
            channel02.write(byteBuffer);
        }

        fileOutputStream.close();
        fileInputStream.close();
    }

    /**
     * 使用transferFrom直接将channel中的内容copy到另外一个channel
     *
     * @throws IOException
     */
    @Test
    public void copyFile() throws IOException {
        FileInputStream fileInputStream = new FileInputStream("1.txt");
        FileChannel channel01 = fileInputStream.getChannel();
        FileOutputStream fileOutputStream = new FileOutputStream("1copy.txt");
        FileChannel channel02 = fileOutputStream.getChannel();

//        channel01.transferTo(0, channel01.size(), channel02);
        channel02.transferFrom(channel01, 0, channel01.size());

        channel02.close();
        fileOutputStream.close();
        channel01.close();
        fileInputStream.close();
    }
}
